home *** CD-ROM | disk | FTP | other *** search
- /*** [getfiles.c]
- *
- * ディレクトリ情報 関連 (C)ささがわ
- *
- * For GNU C Compiler (GCC) Version 1.39
- *
- ***/
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <dos.h>
- #include "jstring.h"
- #include "getfiles.h"
-
- #define DEFAULT_BUF 30
- #define ADD_BUF 50
-
- #define STBUF_RETRY -1
- #define STBUF_FATAL -2
-
- typedef unsigned char Uchar;
-
- static files *buf = NULL;
-
- static int Set_buf(unsigned *);
- static int Set_buf_again(int);
- static void Sort_ext(files **, unsigned);
- static void Sort_date(files **, unsigned);
- static void Sort_name(files **, unsigned);
- static void Sort_non(files **, unsigned);
- static int cmp_dirornot(files **, files **);
- static int cmp_base(files **, files **);
- static int cmp_ext(files **, files **);
- static int cmp_date(files **, files **);
- static int cmp_name(files **, files **);
- static int cmp_non(files **, files **);
- static Uchar *get_extptr(Uchar *);
-
- int Getfiles(int type, get_f *gf, int mode) {
- int n;
- unsigned n_file;
- unsigned n_dir;
- unsigned mf = DEFAULT_BUF;
- files **ptr;
-
- if (mode == 0) {
- while ((n = Set_buf(&mf)) == STBUF_RETRY)
- mf += ADD_BUF;
- if (n == STBUF_FATAL) {
- gf->pbuf = NULL;
- return 1;
- }
- ptr = (files **)(buf + mf);
- n_file = n;
- n_dir = 0;
-
- for (n = 0;n < mf;n++)
- ptr[n] = buf + n;
- } else {
- ptr = gf->pbuf;
- n_file = gf->nfiles;
- n_dir = gf->ndir;
- }
- if (n_file == 0) {
- gf->pbuf = ptr;
- gf->nfiles = n_file;
- gf->ndir = n_dir;
- return 0;
- }
-
- /* ディレクトリ分離 */
- qsort((void *)ptr, (size_t)n_file, (size_t)sizeof(files *), (int (*)(const void *, const void *))cmp_dirornot);
-
- n = 0;
- while (ptr[n]->attr & _A_SUBDIR && n < n_file)
- n++;
- n_dir = n;
-
- switch (type) {
- case GF_SEXT:
- Sort_name(ptr, n_dir);
- Sort_ext(ptr + n_dir, n_file - n_dir);
- break;
-
- case GF_SDATE:
- Sort_date(ptr, n_dir);
- Sort_date(ptr + n_dir, n_file - n_dir);
- break;
-
- case GF_SNAME:
- Sort_name(ptr, n_dir);
- Sort_name(ptr + n_dir, n_file - n_dir);
- break;
-
- default:
- Sort_non(ptr, n_dir);
- Sort_non(ptr + n_dir, n_file - n_dir);
- break;
- }
-
- gf->pbuf = ptr;
- gf->nfiles = n_file;
- gf->ndir = n_dir;
- return 0;
- }
-
- static int Set_buf(unsigned *cap_buf) {
- int n_file;
- unsigned atr = _A_NORMAL | _A_RDONLY | _A_SUBDIR | _A_ARCH;
- struct find_t ft;
-
- Gf_bufrel();
- if ((buf = (files *)malloc(*cap_buf * (sizeof(files) + sizeof(files *)))) == NULL)
- return STBUF_FATAL;
-
- n_file = 0;
- if (!_dos_findfirst("*.*", atr, &ft)) {
- if (strcmp(".", ft.name) || !(ft.attrib & _A_SUBDIR)) {
- strcpy((char *)buf[n_file].name, (const char *)ft.name);
- buf[n_file].attr = ft.attrib;
- buf[n_file].dt = ft.wr_date;
- buf[n_file].tm = ft.wr_time;
- buf[n_file].ord = n_file;
- buf[n_file++].sz = ft.size;
- }
- if (n_file >= *cap_buf) {
- if (Set_buf_again(*cap_buf))
- return STBUF_RETRY;
- *cap_buf += ADD_BUF;
- }
-
- while (!_dos_findnext(&ft)) {
- if (strcmp(".", ft.name) || !(ft.attrib & _A_SUBDIR)) {
- strcpy((char *)buf[n_file].name, (const char *)ft.name);
- buf[n_file].attr = ft.attrib;
- buf[n_file].dt = ft.wr_date;
- buf[n_file].tm = ft.wr_time;
- buf[n_file].ord = n_file;
- buf[n_file++].sz = ft.size;
- }
- if (n_file >= *cap_buf) {
- if (Set_buf_again(*cap_buf))
- return STBUF_RETRY;
- *cap_buf += ADD_BUF;
- }
- }
- }
-
- return n_file;
- }
-
- static int Set_buf_again(int n) {
- files *buf2;
-
- if ((buf2 = (files *)malloc((n + ADD_BUF) * (sizeof(files) + sizeof(files *)))) == NULL)
- return -1;
- memcpy(buf2, buf, n * (sizeof(files) + sizeof(files *)));
- free(buf);
- buf = buf2;
-
- return 0;
- }
-
- /* 拡張子でソートし、そのうえでベース名でソートする関数 */
- static void Sort_ext(files **ptr, unsigned no) {
- int n = 0;
-
- qsort((void *)ptr, (size_t)no, (size_t)sizeof(files *), (int (*)(const void *, const void *))cmp_ext);
-
- while (n < no) {
- Uchar *startptr;
- unsigned start;
-
- start = n;
- startptr = get_extptr((Uchar *)ptr[n++]->name);
- while (!strcmp((const char *)startptr, (const char *)get_extptr((Uchar *)(ptr[n]->name))) && n < no)
- n++;
- qsort((void *)(ptr + start), (size_t)(n - start), (size_t)sizeof(files *), (int (*)(const void *, const void *))cmp_base);
- }
- }
-
- /* 作成日時でソートする関数 */
- static void Sort_date(files **ptr, unsigned no) {
- int n = 0;
-
- qsort((void *)ptr, (size_t)no, (size_t)sizeof(files *), (int (*)(const void *, const void *))cmp_date);
-
- while (n < no) {
- int t, d, st;
-
- st = n;
- d = ptr[n]->dt; t = ptr[n++]->tm;
- while (d == ptr[n]->dt && t == ptr[n]->tm && n < no)
- n++;
- qsort((void *)(ptr + st), (size_t)(n - st), (size_t)sizeof(files *), (int (*)(const void *, const void *))cmp_name);
- }
- }
-
- /* ファイル名全体でソートする関数 */
- static void Sort_name(files **ptr, unsigned no) {
- qsort((void *)ptr, (size_t)no, (size_t)sizeof(files *), (int (*)(const void *, const void *))cmp_name);
- }
-
- /* ディレクトリ順にソートする関数 */
- static void Sort_non(files **ptr, unsigned no) {
- qsort((void *)ptr, (size_t)no, (size_t)sizeof(files *), (int (*)(const void *, const void *))cmp_non);
- }
-
- /* qsort関数用、サブディレクトリを識別する関数 */
- static int cmp_dirornot(files **a, files **b) {
- if ((*a)->attr & _A_SUBDIR && (*b)->attr & _A_SUBDIR)
- return 0;
- else if ((*a)->attr & _A_SUBDIR)
- return -1;
- else if ((*b)->attr & _A_SUBDIR)
- return 1;
- else
- return 0;
- }
-
- /* qsort関数用、ベース名を比較する関数 */
- static int cmp_base(files **a, files **b) {
- Uchar c[13], d[13], *e;
-
- strcpy((char *)c, (const char *)(*a)->name);
- if ((e = jstrchr(c, '.')) != NULL)
- *e = '\0';
- strcpy((char *)d, (const char *)(*b)->name);
- if ((e = jstrchr(d, '.')) != NULL)
- *e = '\0';
- return jstrcmp(c, d);
- }
-
- /* qsort関数用、拡張子を比較する関数 */
- static int cmp_ext(files **a, files **b) {
- return jstrcmp(get_extptr((Uchar *)(*a)->name), get_extptr((Uchar *)(*b)->name));
- }
-
- /* qsort関数用、作成日時を比較する関数 */
- static int cmp_date(files **a, files **b) {
- unsigned long d1, d2;
-
- d1 = ((*a)->dt << 16) + (*a)->tm;
- d2 = ((*b)->dt << 16) + (*b)->tm;
- if (d1 > d2)
- return 1;
- else if (d1 < d2)
- return -1;
- else
- return 0;
- }
-
- /* qsort関数用、ファイル名全体を比較する関数 */
- static int cmp_name(files **a, files **b) {
- if ((*a)->name[0] == '.' || (*b)->name[0] == '.')
- return jstrcmp((Uchar *)(*a)->name, (Uchar *)(*b)->name);
- else
- return jstrcmp((Uchar *)(*a)->name, (Uchar *)(*b)->name);
- }
-
- /* qsort関数用、ディレクトリ順を比較する関数 */
- static int cmp_non(files **a, files **b) {
- if ((*a)->ord > (*b)->ord)
- return 1;
- else if ((*a)->ord < (*b)->ord)
- return -1;
- else
- return 0;
- }
-
- /* 拡張子へのポインタを返す関数 */
- static Uchar *get_extptr(Uchar *a) {
- Uchar *b;
-
- if ((b = jstrchr(a, '.')) == NULL)
- return (a + strlen((char *)a));
- else
- return (b + 1);
- }
-
- void Gf_bufrel(void) {
- free(buf);
- buf = NULL;
- }
-
- int Split_fname(const char *f_name, unsigned atr, char *buf_base, char *buf_ext) {
- int ret;
- char *a;
- static const char *exec_ext[] = {
- ".COM", ".EXE", ".EXP", ".BAT", ""
- };
-
- if ((a = strchr(f_name, '.')) == NULL) {
- strcpy(buf_base, f_name);
- buf_ext[0] = '\0';
- } else {
- buf_base[0] = '\0';
- strncat(buf_base, f_name, a - f_name);
- strcpy(buf_ext, a);
- }
-
- if (atr & _A_SUBDIR) {
- ret = EX_DIR;
- } else {
- int i;
-
- ret = EX_OTHER;
- for (i = 0; exec_ext[i][0]; i++) {
- if (!stricmp(buf_ext, exec_ext[i])) {
- ret = EX_EXE;
- break;
- }
- }
- }
-
- return ret;
- }
-